from abc import ABCMeta, abstractmethod

class DataModel:

    __metaclass__ = ABCMeta

    @abstractmethod
    def batches():
        """Доступ ко всем пачкам"""
        pass

    @abstractmethod
    def groups(self):
        """Доступ ко всем группам проверки"""
        pass


class Batches:

    __metaclass__ = ABCMeta
    
    @abstractmethod
    def add(self, number, papers_count):
        """Добавление пачки с номером number и количеством работ papers_count"""
        pass

    @abstractmethod
    def all(self):
        """Все пачки (список объектов или итератор)"""
        pass

    @abstractmethod
    def find(self, number):
        """Поиск пачки с номером number"""
        pass

    def totalCompleteProblems(self, check_num=None):
        """Общее количество проверенных задач по всем пачкам"""
        return sum(map(lambda b: b.completeProblems(check_num), self.all()))


class Batch:

    __metaclass__ = ABCMeta

    @abstractmethod
    def checkedProblems(self, check_num):
        """Список проверенных задач за проверку check_num"""
        pass

    @abstractmethod
    def completeProblems(self, check_num=None):
        """Общее количество проверенных задач.
           Если check_num не равно None, то количество 
           проверенных задач по конкретной проверке"""
        pass

    @abstractmethod
    def markCompleted(self, problem_num, check_num=None):
        """Пометить задачу problem_num как проверенную"""
        pass

    @abstractmethod
    def sendTo(self, problem_num):
        """Выдать пачку на проверку задачи problem_num"""
        pass

    @abstractmethod
    def return(self, complete=True):
        """Вернуть пачку на стол"""
        pass
        
    @abstractmethod
    def currentGroup(self):
        """Текущая группа проверки, None, если пачка лежит на столе"""
        pass

    @abstractmethod
    def number(self):
        """Номер пачки"""
        pass

    def name(self):
        """Строковое имя пачки"""
        if self.number() > 9:
            return str(self.number())
        else:
            return "0" + str(self.number())

    @abstractmethod
    def markAsSelected(self):
        pass


class Groups:

    __metaclass__ = ABCMeta


class Group:

    __metaclass__ = ABCMeta

